<!doctype html>
<html lang="zh-CN">
<head><meta name="generator" content="Hexo 3.8.0">
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=11,IE=10,IE=9,IE=8">
    <meta name="baidu-site-verification" content="dIcXMeY8Ya">
    
    <title>代理模式 | blog</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
    <meta name="keywords" content="Jim, 服务端, Java, Java开发">
    <meta name="description" content="Jim个人学习记录">

    
    <link rel="alternative" href="/atom.xml" title="blog" type="application/atom+xml">
    
    
    <link rel="shortcut icon" href="/favicon.ico">
    
    <link rel="stylesheet" href="/css/style.css">
    <!--[if lt IE 9]>
    <script src="/js/html5.js"></script>
    <![endif]-->
    
<script>
    var _hmt = _hmt || [];
    (function() {
        var hm = document.createElement("script");
        hm.src = "//hm.baidu.com/hm.js?fd459238242776d173cdc64918fb32f2";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
    })();
</script>


</head>
</html>
<body class="home">
    <!--[if lt IE 9]>
    <div class="browsehappy">
        当前网页 <strong>不支持</strong>
        你正在使用的浏览器. 为了正常的访问, 请 <a href="http://browsehappy.com/">升级你的浏览器</a>.
    </div>
    <![endif]-->

    <!-- 博客头部 -->
    <header class="header">
    <section class="container header-main">
        <div class="logo">
            <a href="/">
                <div class="cover">
                    <span class="name">blog</span>
                    <span class="description"></span>
                </div>
            </a>
        </div>
        <div class="dropnav icon-paragraph-justify" id="JELON__btnDropNav"></div>
        <ul class="menu hidden" id="JELON__menu">
            
            <li rel="/2019/07/11/design_pattern_代理模式/index.html" class="item ">
                <a href="/" title="首页" class="icon-home">&nbsp;首页</a>
            </li>
            
            <li rel="/2019/07/11/design_pattern_代理模式/index.html" class="item ">
                <a href="/about/" title="关于" class="icon-about">&nbsp;关于</a>
            </li>
            
            <li rel="/2019/07/11/design_pattern_代理模式/index.html" class="item ">
                <a href="/comment/" title="留言" class="icon-comment">&nbsp;留言</a>
            </li>
            
        </ul>
        <div class="profile clearfix">
            <div class="feeds fl">
                
                
                <p class="links">
                    
                        <a href="https://github.com/starryming" target="_blank">Github</a>
                        |
                    
                        <a href="http://ljmstarry.gitee.io" target="_blank">Hosted by Coding Pages</a>
                        
                    
                </p>
                <p class="sns">
                    
                        <a href="http://weibo.com/" class="sinaweibo" target="_blank"><b>■</b> 新浪微博</a>
                    
                        <a href="https://www.facebook.com/" class="qqweibo" target="_blank"><b>■</b> Facebook</a>
                    
                    <a href="javascript: void(0);" class="wechat">
                        <b>■</b>
                        公众号
                        <span class="popover">
                            <img src="/img/wechat_mp.jpg" width="120" height="120" alt="我的微信订阅号">
                            <i class="arrow"></i>
                        </span>
                    </a>
                </p>
                
            </div>
            <div class="avatar fr">
                <img src="/img/timg.jpg" alt="avatar" title="Jim">
            </div>
        </div>
    </section>
</header>


    <!-- 博客正文 -->
    <div class="container body clearfix">
        <section class="content">
            <div class="content-main widget">
                <!-- 文章页 -->
<!-- 文章 -->
<article class="post article">
    <header class="text-center">
        <h3 class="post-title"><span>代理模式</span></h3>
    </header>
    <p class="post-meta text-center">
        Jim 发表于
        <time datetime="2019-07-11T05:44:45.000Z">2019-07-11</time>
    </p>
    <div class="post-content">
        <h2 id="代理模式-Proxy"><a href="#代理模式-Proxy" class="headerlink" title="代理模式(Proxy)"></a>代理模式(Proxy)</h2><blockquote>
<p>假如我们打算去金门游玩一天，这时候就需要办通行证签注等，而依靠旅行社我们就可以单纯游玩了，办通行证等事宜旅行社会帮我们全部解决。而这里，旅行社扮演了代理对象，我们则是真实角色。</p>
</blockquote>
<a id="more"></a>
<h4 id="问题："><a href="#问题：" class="headerlink" title="问题："></a>问题：</h4><ul>
<li>谈谈你对代理模式的理解？</li>
<li>静态代理和动态代理有什么区别？</li>
<li>如何实现动态代理？</li>
<li>Spring AOP用的是哪种设计模式？</li>
</ul>
<h4 id="思路："><a href="#思路：" class="headerlink" title="思路："></a>思路：</h4><p>定义一个抽象角色，让<strong>代理角色</strong>和<strong>真实角色</strong>分别去实现它。  </p>
<ol>
<li>真实角色：实现抽象角色，定义真实角色所要实现的业务逻辑，<strong>供代理角色调用</strong>。它只关注真正的业务逻辑，比如拍戏。</li>
<li>代理角色：实现抽象角色，是真实角色的代理，通过真实角色的业务逻辑方法来实现抽象方法，并可以附加自己的操作，比如谈合同，布置场地等等。</li>
</ol>
<h4 id="代理模式UML图："><a href="#代理模式UML图：" class="headerlink" title="代理模式UML图："></a>代理模式UML图：</h4><p><img src="https://i.loli.net/2019/07/09/5d243c314246597249.png" alt></p>
<h4 id="什么是代理模式："><a href="#什么是代理模式：" class="headerlink" title="什么是代理模式："></a>什么是代理模式：</h4><p>​    1、对于对象的访问，通过代理进行控制。其设计结构我们借助UML图进行学习：</p>
<p>​        <strong>Subject:</strong> 接口对象，抽象出核心功能。</p>
<p>​        <strong>RealSubjet:</strong>    真实对象，这里是核心功能的实现。</p>
<p>​        <strong>Proxy:</strong>    代理对象，这里辅助核心功能进行，如预处理，善后处理等。</p>
<p>​    2、代理模式分为<strong>静态代理</strong>和<strong>动态代理【JDK/CGLIB】</strong>，</p>
<p>​        静态代理是我们自己创建一个代理类，而动态代理是程序自动帮我们生成一个代理类，无需我们创建。</p>
<p>【<strong>静态代理</strong>】</p>
<p>抽象接口：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Star</span> </span>&#123;</span><br><span class="line">    </span><br><span class="line">	String STAR_SING = <span class="string">"sing"</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 唱歌</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">sing</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>真实对象：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RealStar</span> <span class="keyword">implements</span> <span class="title">Star</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 唱歌</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sing</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"RealStar(贾静雯).sing()"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>代理对象：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ProxyStar</span> <span class="keyword">implements</span> <span class="title">Star</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Star star;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 传进真实对象</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> star 真实对象</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ProxyStar</span><span class="params">(Star star)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>();</span><br><span class="line">        <span class="keyword">this</span>.star = star;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 唱歌</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sing</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        confer();</span><br><span class="line">        <span class="comment">// 核心业务需要真实对象来完成</span></span><br><span class="line">        star.sing();</span><br><span class="line">        collectMoney();</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 合同签订</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">confer</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"ProxyStar.confer() 签谈合同"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 费用收取</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">collectMoney</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"ProxyStar.collectMoney() 收出场费用"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>测试类：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">    * 测试静态代理</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">   <span class="meta">@Test</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">TestProxy</span><span class="params">()</span></span>&#123;</span><br><span class="line">       Star real = <span class="keyword">new</span> RealStar();</span><br><span class="line">       Star proxy = <span class="keyword">new</span> ProxyStar(real);</span><br><span class="line"></span><br><span class="line">       proxy.sing();</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>
<p>【<strong>动态代理</strong>】动态代理由<strong>JDK动态代理</strong>和<strong>CGLIB动态代理</strong>。</p>
<p>动态代理前提了解：1、<strong>java.lang.reflect.Proxy</strong>类    <strong>newProxyInstance</strong>方法</p>
<p>​                                  2、<strong>java.lang.reflect.InvocationHandler</strong></p>
<ul>
<li><strong>JDK动态代理</strong></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JdkProxyHandler</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Object star;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">JdkProxyHandler</span><span class="params">(Star star)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>();</span><br><span class="line">        <span class="keyword">this</span>.star = star;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 返回jdk动态代理对象,lambda写法</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">getProxyInstance</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> Proxy.newProxyInstance(star.getClass().getClassLoader(),</span><br><span class="line">                star.getClass().getInterfaces(), (proxy, method, args) -&gt; &#123;</span><br><span class="line">                    <span class="comment">// 核心业务,调用代理对象的sing方法</span></span><br><span class="line">                    <span class="keyword">if</span> (Star.STAR_SING.equals(method.getName())) &#123;</span><br><span class="line">                        System.out.println(<span class="string">"合同签订(Lambda写法)"</span>);</span><br><span class="line">                        Object object = method.invoke(star, args);</span><br><span class="line">                        System.out.println(<span class="string">"结束收费(Lambda写法)"</span>);</span><br><span class="line">                        <span class="keyword">return</span> object;</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">                &#125;);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 返回jdk动态代理对象</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">getProxyInstanceOther</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> Proxy.newProxyInstance(star.getClass().getClassLoader(),</span><br><span class="line">                star.getClass().getInterfaces(),</span><br><span class="line">                <span class="keyword">new</span> InvocationHandler() &#123;</span><br><span class="line">                    <span class="meta">@Override</span></span><br><span class="line">                    <span class="function"><span class="keyword">public</span> Object <span class="title">invoke</span><span class="params">(Object proxy, Method method, Object[] args)</span> <span class="keyword">throws</span> Throwable </span>&#123;</span><br><span class="line">                        <span class="keyword">if</span> (Star.STAR_SING.equals(method.getName())) &#123;</span><br><span class="line">                            System.out.println(<span class="string">"合同签订(匿名内部类)"</span>);</span><br><span class="line">                            Object object = method.invoke(star, args);</span><br><span class="line">                            System.out.println(<span class="string">"结束收费(匿名内部类)"</span>);</span><br><span class="line">                            <span class="keyword">return</span> object;</span><br><span class="line">                        &#125;</span><br><span class="line">                        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>测试：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testJDKProxyHandler</span><span class="params">()</span> </span>&#123;</span><br><span class="line">       Star star = <span class="keyword">new</span> RealStar();</span><br><span class="line">       JdkProxyHandler jdkProxyHandler = <span class="keyword">new</span> JdkProxyHandler(star);</span><br><span class="line"></span><br><span class="line">       Star jdkProxyHandlerProxyInstance = (Star) jdkProxyHandler.getProxyInstance();</span><br><span class="line">       jdkProxyHandlerProxyInstance.sing();</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>
<ul>
<li><strong>CGLIB动态代理</strong></li>
</ul>
<p>​     JDK动态代理，需要实现类通过接口定义业务方法，那么，一旦我们需要代理的类没有父类接口呢？这时候如何实现动态代理？我们可以通过CGLIB实现。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CglibProxyHandler</span> <span class="keyword">implements</span> <span class="title">MethodInterceptor</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Object star;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">getProxyIndtance</span><span class="params">(<span class="keyword">final</span> Object star)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.star = star;</span><br><span class="line">        <span class="comment">// Enhancer类是CGLIB中的一个字节码增强器，它可以方便的对你想要处理的类进行扩展</span></span><br><span class="line">        Enhancer enhancer = <span class="keyword">new</span> Enhancer();</span><br><span class="line">        <span class="comment">// 将被代理的对象设置成父类</span></span><br><span class="line">        enhancer.setSuperclass(<span class="keyword">this</span>.star.getClass());</span><br><span class="line">        <span class="comment">// 回调方法，设置拦截器</span></span><br><span class="line">        enhancer.setCallback(<span class="keyword">this</span>);</span><br><span class="line">        <span class="comment">// 动态创建一个代理类</span></span><br><span class="line">        <span class="keyword">return</span> enhancer.create();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">intercept</span><span class="params">(Object object, Method method, Object[] objects, MethodProxy methodProxy)</span> <span class="keyword">throws</span> Throwable </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"合同签订"</span>);</span><br><span class="line">        <span class="comment">// 核心业务</span></span><br><span class="line">        Object result = methodProxy.invokeSuper(object, objects);</span><br><span class="line">        System.out.println(<span class="string">"收费"</span>);</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testCglibProxyHandler</span><span class="params">()</span> </span>&#123;</span><br><span class="line">       Star star = <span class="keyword">new</span> RealStar();</span><br><span class="line">       Star proxy = (Star) <span class="keyword">new</span> CglibProxyHandler().getProxyIndtance(star);</span><br><span class="line"></span><br><span class="line">       proxy.sing();</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>
<p>​    <strong>关于CGLIB动态代理的Enhancer：</strong></p>
<h4 id="Spring-AOP使用的代理"><a href="#Spring-AOP使用的代理" class="headerlink" title="Spring AOP使用的代理"></a>Spring AOP使用的代理</h4><p>如果代理对象实现了接口，默认情况下将会走JDK代理模式，如果对象未实现接口，将会走CGLIB代理。</p>
<p>(可以通过配置，更改代理走向)</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DefaultAopProxyFactory</span> <span class="keyword">implements</span> <span class="title">AopProxyFactory</span>, <span class="title">Serializable</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> AopProxy <span class="title">createAopProxy</span><span class="params">(AdvisedSupport config)</span> <span class="keyword">throws</span> AopConfigException </span>&#123;</span><br><span class="line">        <span class="comment">/*	进行JDK 和 CGLIB代理的选取</span></span><br><span class="line"><span class="comment">         *	config.isOptimize()与config.isProxyTargetClass()默认情况下都为false</span></span><br><span class="line"><span class="comment">         *	=&gt; 选定用何种代理 取决于hasNoUserSuppliedProxyInterfaces(config)</span></span><br><span class="line"><span class="comment">         *	   当然我们也可以进行配置,使得固定用CGLIB动态代理</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">		<span class="keyword">if</span> (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) &#123;</span><br><span class="line">			Class&lt;?&gt; targetClass = config.getTargetClass();</span><br><span class="line">			<span class="keyword">if</span> (targetClass == <span class="keyword">null</span>) &#123;</span><br><span class="line">				<span class="keyword">throw</span> <span class="keyword">new</span> AopConfigException(<span class="string">"TargetSource cannot determine target class: "</span> +</span><br><span class="line">						<span class="string">"Either an interface or a target is required for proxy creation."</span>);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">if</span> (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) &#123;</span><br><span class="line">				<span class="keyword">return</span> <span class="keyword">new</span> JdkDynamicAopProxy(config);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">new</span> ObjenesisCglibAopProxy(config);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">else</span> &#123;</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">new</span> JdkDynamicAopProxy(config);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">/**</span></span><br><span class="line"><span class="comment">	 * Determine whether the supplied &#123;<span class="doctag">@link</span> AdvisedSupport&#125; has only the</span></span><br><span class="line"><span class="comment">	 * &#123;<span class="doctag">@link</span> org.springframework.aop.SpringProxy&#125; interface specified</span></span><br><span class="line"><span class="comment">	 * (or no proxy interfaces specified at all).</span></span><br><span class="line"><span class="comment">	 * 判断代理的对象是否有实现接口</span></span><br><span class="line"><span class="comment">	 */</span></span><br><span class="line">	<span class="function"><span class="keyword">private</span> <span class="keyword">boolean</span> <span class="title">hasNoUserSuppliedProxyInterfaces</span><span class="params">(AdvisedSupport config)</span> </span>&#123;</span><br><span class="line">		Class&lt;?&gt;[] ifcs = config.getProxiedInterfaces();</span><br><span class="line">		<span class="keyword">return</span> (ifcs.length == <span class="number">0</span> || (ifcs.length == <span class="number">1</span> &amp;&amp; SpringProxy.class.isAssignableFrom(ifcs[<span class="number">0</span>])));</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

    </div>
    <p class="post-meta">
        <span class="post-cat">分类：
            <a class="cat-link" href="/categories/technology/">technology</a>
        </span>
        <span class="post-tags">
            标签：
            
    
        <a href="/tags/设计模式/" title="设计模式">设计模式</a>
    

        </span>
    </p>
</article>
<!-- 分享按钮 -->

  <div class="article-share clearfix text-center">
    <div class="share-area">
      <span class="share-txt">分享到：</span>
      <a href="javascript: window.open('http://service.weibo.com/share/share.php?url=' + encodeURIComponent(location.href) + '&title=' + document.title + '&language=zh_cn');" class="share-icon weibo"></a>
      <a href="javascript: alert('请复制链接到微信并发送');" class="share-icon wechat"></a>
      <a href="javascript: window.open('http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=' + encodeURIComponent(location.href) + '&title=' + document.title);" class="share-icon qqzone"></a>
      <a href="javascript: window.open('http://connect.qq.com/widget/shareqq/index.html?url=' + encodeURIComponent(location.href) + '&desc=Jim个人博客&title=' + document.title + '&callback=' + encodeURIComponent(location.href));" class="share-icon qq"></a>
      <a href="javascript: window.open('http://shuo.douban.com/!service/share?href=' + encodeURIComponent(location.href) + '&name=' + document.title + '&text=' + document.title);" class="share-icon douban"></a>
    </div>
  </div>


<!-- 上一篇/下一篇 -->

<div class="article-nav clearfix">
    
    <span class="prev fl">
        上一篇<br>
        <a href="/2019/07/11/Class源码/">
            
                Class源码
            
        </a>
    </span>
    

    
    <span class="next fr">
        下一篇<br>
        <a href="/2019/06/24/SpringBoot的Shiro引起事务失效/">
            
                SpringBoot的Shiro引起事务失效
            
        </a>
    </span>
    
</div>

<!-- 文章评论 -->

  <script src="/js/comment.js"></script>
  <div id="comments" class="comment">
    <!--
    <div class="sign-bar">
      GitHub 已登录!
      <span class="sign-link">登出</span>
    </div>
    <section class="box">
      <div class="com-avatar"><img src="/img/jelon.jpg" alt="avatar"></div>
      <div class="com-text">
        <div class="main">
          <textarea class="text-area-edited show" placeholder="欢迎评论！"></textarea>
          <div class="text-area-preview"></div>
        </div>
        <div class="switch">
          <div class="switch-item on">编辑</div>
          <div class="switch-item">预览</div>
        </div>
        <div class="button">提交</div>
      </div>
    </section>
    <section class="tips">注：评论支持 markdown 语法！</section>
    <section class="list-wrap">
      <ul class="list">
        <li>
          <div class="user-avatar">
            <a href="/">
              <img src="/img/jelon.jpg" alt="user-avatar">
            </a>
          </div>
          <div class="user-comment">
            <div class="user-comment-header">
              <span class="post-name">张德龙</span>
              <span class="post-time">2017年12月12日</span>
              <span class="like liked">已赞</span>
              <span class="like-num">2</span>
            </div>
            <div class="user-comment-body">333333</div>
          </div>
        </li>
        <li>
          <div class="user-avatar">
            <a href="/">
              <img src="/img/jelon.jpg" alt="user-avatar">
            </a>
          </div>
          <div class="user-comment">
            <div class="user-comment-header">
              <span class="post-name">刘德华</span>
              <span class="post-time">2017年12月12日</span>
              <span class="like">点赞</span>
              <span class="like-num">2</span>
            </div>
            <div class="user-comment-body">vvvvv</div>
          </div>
        </li>
      </ul>
      <div class="page-nav">
        <a href="javascript: void(0);" class="item">1</a>
        <a href="javascript: void(0);" class="item">2</a>
        <a href="javascript: void(0);" class="item current">3</a>
      </div>
    </section>
    -->
  </div>
  <script>
  JELON.Comment({
    container: 'comments',
    label: 'design_pattern_代理模式' || '2019/07/11/design_pattern_代理模式/',
    owner: 'your_github_id',
    repo: 'your_blog_comments',
    clientId: 'your_client_id',
    clientSecret: 'your_client_secret'
  });
  </script>


            </div>

        </section>
        <!-- 侧栏部分 -->
<aside class="sidebar">
    <section class="widget">
        <h3 class="widget-hd"><strong>文章分类</strong></h3>
        <!-- 文章分类 -->
<ul class="widget-bd">
    
    <li>
        <a href="/categories/linus/">linus</a>
        <span class="badge">(4)</span>
    </li>
    
    <li>
        <a href="/categories/technology/">technology</a>
        <span class="badge">(8)</span>
    </li>
    
    <li>
        <a href="/categories/Reading/">Reading</a>
        <span class="badge">(13)</span>
    </li>
    
    <li>
        <a href="/categories/others/">others</a>
        <span class="badge">(1)</span>
    </li>
    
    <li>
        <a href="/categories/linus/technology/">technology</a>
        <span class="badge">(1)</span>
    </li>
    
    <li>
        <a href="/categories/mysql/">mysql</a>
        <span class="badge">(1)</span>
    </li>
    
    <li>
        <a href="/categories/mysql/technology/">technology</a>
        <span class="badge">(1)</span>
    </li>
    
</ul>
    </section>

    
    <section class="widget">
        <h3 class="widget-hd"><strong>热门标签</strong></h3>
        <!-- 文章标签 -->
<div class="widget-bd tag-wrap">
  
    <a class="tag-item" href="/tags/linus/" title="linus">linus (4)</a>
  
    <a class="tag-item" href="/tags/ngnix/" title="ngnix">ngnix (1)</a>
  
    <a class="tag-item" href="/tags/源码学习/" title="源码学习">源码学习 (2)</a>
  
    <a class="tag-item" href="/tags/阅读/" title="阅读">阅读 (13)</a>
  
    <a class="tag-item" href="/tags/Thinking-In-Java/" title="Thinking In Java">Thinking In Java (5)</a>
  
    <a class="tag-item" href="/tags/java/" title="java">java (3)</a>
  
    <a class="tag-item" href="/tags/technology/" title="technology">technology (1)</a>
  
    <a class="tag-item" href="/tags/springBoot/" title="springBoot">springBoot (2)</a>
  
    <a class="tag-item" href="/tags/设计模式/" title="设计模式">设计模式 (3)</a>
  
    <a class="tag-item" href="/tags/test/" title="test">test (1)</a>
  
    <a class="tag-item" href="/tags/Effective-Java/" title="Effective Java">Effective Java (8)</a>
  
    <a class="tag-item" href="/tags/mysql/" title="mysql">mysql (2)</a>
  
    <a class="tag-item" href="/tags/Docker/" title="Docker">Docker (1)</a>
  
</div>
    </section>
    

    

    
    <!-- 友情链接 -->
    <section class="widget">
        <h3 class="widget-hd"><strong>友情链接</strong></h3>
        <!-- 文章分类 -->
<ul class="widget-bd">
    
        <li>
            <a href="https://www.bilibili.com" target="_blank" title="bilibili">哔哩哔哩</a>
        </li>
    
        <li>
            <a href="https://www.baidu.com" target="_blank" title="百度搜索">百度</a>
        </li>
    
</ul>
    </section>
    
</aside>
<!-- / 侧栏部分 -->
    </div>

    <!-- 博客底部 -->
    <footer class="footer">
    &copy;
    
        2016-2020
    

    <a href="/">Jim Loves You</a>
</footer>
<div class="back-to-top" id="JELON__backToTop" title="返回顶部">返回顶部</div>

    <!--博客js脚本 -->
    <!-- 这里放网站js脚本 -->
<script src="/js/main.js"></script>
</body>
</html>